package com.rams.jhms.gui;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeSelectionModel;

import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;

import com.rams.jhms.Config;
import com.rams.jhms.fs.FSFile;
import com.rams.jhms.fs.FSFolder;
import com.rams.jhms.gui.datamodels.FSTableModel;
import com.rams.jhms.gui.datamodels.FSTreeModel;

public class MainForm extends JFrame {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static final JTree fsTree = new JTree();
	private static final JScrollPane fsTreeSC = new JScrollPane(fsTree);
	
	private static FSTableModel fstm = new FSTableModel();
	private static final JTable fsTable = new JTable(fstm);
	private static final JScrollPane fsTableSC = new JScrollPane(fsTable);
	
	private static final JSplitPane leftSideSpliter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, fsTreeSC, new JPanel());
	private static final JSplitPane mainSpliter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, leftSideSpliter, fsTableSC);
	
	private static final JPopupMenu gridMenu = new JPopupMenu();
	
	private static final JMenuBar mainMenu = new JMenuBar();
	
	private static MainForm instance;
	
	public MainForm() {
		super();
		instance = this;
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setJMenuBar(mainMenu);
		
		initMainMenu();
		
		MigLayout ml = new MigLayout(new LC().debug(Config.layoutDebug).wrap());
		this.setLayout(ml);
		
		fsTree.setModel(new FSTreeModel());
		fsTree.setRootVisible(false);
		fsTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		fsTree.addTreeSelectionListener(new TreeSelectionListener() {
			public void valueChanged(TreeSelectionEvent e) {
				FSFolder folder = (FSFolder)fsTree.getLastSelectedPathComponent();
				
				if (folder == null) {
					fstm.setTableData(new ArrayList<FSFile>());
				} else {
					fstm.setTableData(folder.getChildFiles());
				}
			}
		});
		
		fsTable.addKeyListener(new KeyListener() {
			public void keyTyped(KeyEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			public void keyReleased(KeyEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == 115) {
					showEditForm();
				}
			}
		});
		fsTable.addMouseListener(new PopupListener());
		
		mainSpliter.setDividerSize(3);
		mainSpliter.setBorder(null);
		mainSpliter.setDividerLocation(300);
		leftSideSpliter.setDividerSize(3);
		leftSideSpliter.setDividerLocation(350);
		leftSideSpliter.setBorder(null);
		
		this.setContentPane(mainSpliter);
		
		this.setMinimumSize(new Dimension(700, 600));
		
		JMenuItem editMenuItem = new JMenuItem(Config.local.popupMenuItemEdit());
		editMenuItem.addActionListener(new EditActionAdapter());
		gridMenu.add(editMenuItem);
		
		this.setLocationRelativeTo(null); // set window to center
		// TODO: change it. We must set window to last position before application close.
	}
	
	private void initMainMenu() {
		JMenu propsMenu = new JMenu(Config.local.mainMenuSettings());
		JMenuItem item = new JMenuItem(Config.local.mainMenuFolderManager()); 
		item.setActionCommand("fs_manager");
		item.addActionListener(new MainMenuActionAdapter());
		propsMenu.add(item);
		item = new JMenuItem(Config.local.mainMenuAppSettings());
		item.setActionCommand("app_settings");
		item.addActionListener(new MainMenuActionAdapter());
		propsMenu.add(item);
		
		JMenu fileMenu = new JMenu(Config.local.mainMenuFile());
		fileMenu.add(new JSeparator());
		item = new JMenuItem(Config.local.mainMenuExit());
		item.setActionCommand("app_exit");
		item.addActionListener(new MainMenuActionAdapter());		
		fileMenu.add(item);
		
		mainMenu.add(fileMenu);
		mainMenu.add(propsMenu);
	}

	private void showEditForm() {
		if (fsTable.getSelectedRowCount() > 1) { // many files selected
			// TODO: show files edit dialog
		} else { // one file select
			FileEditForm.showForm(fstm.getDataAt(fsTable.getSelectedRow()));
		}
	}
	
	private class PopupListener extends MouseAdapter {
	    public void mousePressed(MouseEvent e) {
	    	if (SwingUtilities.isRightMouseButton(e)) {
	    		int[] curSelection = fsTable.getSelectedRows();
	    		int rowNumber = fsTable.rowAtPoint(e.getPoint());
	    		boolean isSelect = false;
	    		for (int curIndex : curSelection) {
	    			if (curIndex == rowNumber) {
	    				isSelect = true;
	    				break;
	    			}
	    		}
	    		
	    		if (!isSelect)
	    			fsTable.getSelectionModel().setSelectionInterval(rowNumber, rowNumber);
	    	}
	    	showPopup(e);
	    }
	    
	    public void mouseReleased(MouseEvent e) {
	    	showPopup(e);
	    }
	    
	    private void showPopup(MouseEvent e) {
	    	if (e.isPopupTrigger()) {
	    		gridMenu.show(e.getComponent(), e.getX(), e.getY());
	    	}
	    }
	}
	
	class EditActionAdapter implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			showEditForm();
		}
	}

	class MainMenuActionAdapter implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			String command = e.getActionCommand();
			if ("fs_manager".equals(command)) {
				new FSFolderManagerForm(new FSFoldersListChangedAdapter());
			} else if ("app_exit".equals(command)) {
				instance.dispose();
			} else if ("app_settings".equals(command)) {
				(new ApplicationSettingsForm()).setVisible(true);
			}
		}
	}
	
	private class FSFoldersListChangedAdapter implements ListDataListener{
		public void intervalAdded(ListDataEvent e) {
			onDataChange();
		}

		public void intervalRemoved(ListDataEvent e) {
			onDataChange();
		}

		public void contentsChanged(ListDataEvent e) {
			onDataChange();
		}
		
		private void onDataChange() {
			fsTree.setModel(new FSTreeModel());
		}
	}
}
